package com.hyk.controller;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.alicloud.sms.ISmsService;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hyk.domain.User;
import com.hyk.domain.UserAuthAuditRecord;
import com.hyk.domain.UserAuthInfo;
import com.hyk.dto.R;
import com.hyk.dto.UserDto;
import com.hyk.feign.UserServiceFeign;
import com.hyk.model.ChangePasswordVo;
import com.hyk.model.UpdateUserMobileVo;
import com.hyk.service.UserAuthAuditRecordService;
import com.hyk.service.UserAuthInfoService;
import com.hyk.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.xml.bind.ValidationException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@Api(tags = "用户相关接口")
@RequestMapping("/users")
public class UserController implements UserServiceFeign {

    @Resource
    private UserService userService;

    @Resource
    private UserAuthAuditRecordService userAuthAuditRecordService;

    @Resource
    private UserAuthInfoService userAuthInfoService;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Resource
    private ISmsService smsService;

    @GetMapping
    @ApiOperation("分页查询用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile",value = "手机号"),
            @ApiImplicitParam(name = "userId",value = "用户id"),
            @ApiImplicitParam(name = "userName",value = "用户名"),
            @ApiImplicitParam(name = "realName",value = "真实姓名"),
            @ApiImplicitParam(name = "status",value = "状态"),
            @ApiImplicitParam(name = "current",value = "当前页"),
            @ApiImplicitParam(name = "size",value = "每页大小")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> list(@ApiIgnore Page<User> page,
                              String mobile,
                              String userId,
                              String userName,
                              String realName,
                              String status){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (mobile != null && mobile != ""){
            wrapper.like("mobile",mobile);
        }
        if (userId != null && userId != ""){
            wrapper.like("id",userId);
        }
        if (userName != null && userName != ""){
            wrapper.like("username",userName);
        }
        if (realName != null && realName != ""){
            wrapper.like("real_ame",realName);
        }
        if (status != null && status != ""){
            wrapper.eq("status",status);
        }
        wrapper.orderByDesc("created");
        return R.ok(userService.page(page,wrapper));
    }

    @PatchMapping
    @ApiOperation("编辑用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile",value = "手机号"),
            @ApiImplicitParam(name = "id",value = "用户id"),
            @ApiImplicitParam(name = "username",value = "用户名"),
            @ApiImplicitParam(name = "realName",value = "真实姓名"),
            @ApiImplicitParam(name = "status",value = "状态"),
            @ApiImplicitParam(name = "authStatus",value = "实名认证状态"),
            @ApiImplicitParam(name = "countryCode",value = "国际区号"),
            @ApiImplicitParam(name = "email",value = "邮箱"),
            @ApiImplicitParam(name = "idCard",value = "身份证号")
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R update(@RequestBody User user){
        boolean update = userService.updateById(user);
        if (update){
            return R.ok("修改成功");
        }
        return R.fail("修改失败");
    }

    @PostMapping("status")
    @ApiOperation("修改用户状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "状态"),
            @ApiImplicitParam(name = "id", value = "用户id")
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R changeStatus(String id,String status){
        User user = new User();
        user.setId(Long.parseLong(id));
        user.setStatus(Byte.parseByte(status));
        boolean update = userService.updateById(user);
        if (update){
            return R.ok("修改成功");
        }
        return R.fail("修改失败");
    }

    @GetMapping("/info")
    @ApiOperation("查询用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value = "用户id"),
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<User> find(String id){
        return R.ok(userService.getById(Long.parseLong(id)));
    }

    @GetMapping("/directInvites")
    @ApiOperation("用户邀请列表")
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> getDirectInvites(@ApiIgnore Page<User> page,
                                    String userId){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(userId)){
            wrapper.eq("direct_inviteid",userId);
        }
        wrapper.orderByDesc("created");
        return R.ok(userService.page(page,wrapper));
    }

    @GetMapping("/auths")
    @ApiOperation("高级实名认证审核列表")
    //@PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> getList(@ApiIgnore Page<User> page,
                              String mobile,
                              String userId,
                              String userName,
                              String realName,
                              String reviewsStatus){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (mobile != null && mobile != ""){
            wrapper.like("mobile",mobile);
        }
        if (userId != null && userId != ""){
            wrapper.like("id",userId);
        }
        if (userName != null && userName != ""){
            wrapper.like("username",userName);
        }
        if (realName != null && realName != ""){
            wrapper.like("real_ame",realName);
        }
        if (reviewsStatus != null && reviewsStatus != ""){
            wrapper.eq("reviews_status",reviewsStatus);
        }
        wrapper.orderByDesc("last_update_time");
        return R.ok(userService.page(page,wrapper));
    }

    @GetMapping("/auth/info")
    @ApiOperation("用户详情数据")
    public R<UseAuthInfoVo> userInfo(String id){
        User user = userService.getById(Long.parseLong(id));
        List<UserAuthInfo> userAuthInfoList = Collections.emptyList();
        List<UserAuthAuditRecord> authAuditRecordList = Collections.emptyList();
        if (user != null){
            userAuthInfoList = userAuthInfoService.getUserAuthInfoByUserId(id);
            authAuditRecordList = userAuthAuditRecordService.getUserAuthAuditRecordList(id);
        }
        return R.ok(new UseAuthInfoVo(user,userAuthInfoList,authAuditRecordList));
    }

    @PostMapping("/auths/status")
    @ApiOperation("处理审核")
    public R updateUserAuthStatus(Long id, Byte authStatus, Long authCode, String remark){
        userService.updateUserAuthStatus(id,authStatus,authCode,remark);
        return R.ok();
    }

    @GetMapping("/current/info")
    @ApiOperation("获取当前登录用户的详情")
    public R<User> info(){
        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        User user = userService.getById(Long.parseLong(userId));
        user.setPassword("**********");
        user.setPaypassword("**********");
        return R.ok(user);
    }

    @PostMapping("/authAccount")
    @ApiOperation("用户实名认证")
    public R authAccount(@RequestBody User user) throws ValidationException {
        userService.authAccount(user);
        return R.ok();
    }

    @PostMapping("/authUser")
    public R<Object> authUser(@RequestBody String[] imgas){
        userService.authUser(imgas);
        return R.ok();
    }

    @PostMapping("/updatePhone")
    @ApiOperation(value = "修改手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "UpdateUserMobileVo",value = "UpdateUserMobileVo 的json数据")
    })
    public R<Object> updatePhone(@RequestBody UpdateUserMobileVo updateUserMobileVo){

        userService.updatePhone(updateUserMobileVo);

        return R.ok();

    }


    @GetMapping("/checkTel")
    @ApiOperation(value = "检查新的手机号是否可用,如可用,则给该新手机发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile" ,value = "新的手机号"),
            @ApiImplicitParam(name = "countryCode" ,value = "手机号的区域")
    })
    public R checkTel(String countryCode,String mobile) {

        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(mobile); //发送给谁
        // Required:SMS-SignName-could be found in sms console
        sendSmsRequest.setTemplateCode("1234556"); // 模板的Code--动态改变
        // Required:The param of sms template.For exmaple, if the template is "Hello,your verification code is ${code}". The param should be like following value
        //生成随机数
        String code = RandomUtil.randomNumbers(6);
        // 需要把code 保存到redis 里面
        // key: SMS:VERIFY_OLD_PHONE:15827293117     value: 123456
        redisTemplate.opsForValue().set("SMS:" + "VERIFY_NEW_PHONE" + ":" + mobile, code,5, TimeUnit.MINUTES);
        sendSmsRequest.setTemplateParam("{\"code\":\"" + code + "\"}");
        try {
            smsService.sendSmsRequest(sendSmsRequest);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return R.ok();

    }
    @PostMapping("/updateLoginPassword")
    @ApiOperation("修改密码")
    public R changePassword(@RequestBody ChangePasswordVo changePasswordVo){
        Boolean change = userService.changePassword(changePasswordVo);
        if (change){
            return R.ok();
        }
        return R.fail();
    }

    @PostMapping("/updatePayPassword")
    @ApiOperation("修改支付密码")
    public R changePayPassword(@RequestBody ChangePasswordVo changePasswordVo){
        Boolean change = userService.changePayPassword(changePasswordVo);
        if (change){
            return R.ok();
        }
        return R.fail();
    }

    @PostMapping("/setPayPassword")
    @ApiOperation("重置支付密码")
    public R rePayPassword(@RequestBody ChangePasswordVo changePasswordVo){
        Boolean change = userService.rePayPassword(changePasswordVo);
        if (change){
            return R.ok();
        }
        return R.fail();
    }

    @GetMapping("/invites")
    @ApiOperation("用户邀请列表")
    public R<List<User>> invitesList(){
        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("direct_inviteid",userId);
        List<User> list = userService.list(wrapper);
        return R.ok(list);
    }

    @Override
    @GetMapping("/basic/users")
    public Map<Long, UserDto> getBasicUsers(List<Long> ids,String mobile,String username) {
        Map<Long, UserDto> map = userService.getBasicUsers(ids,mobile,username);
        return map;
    }

    @PostMapping("/register")
    @ApiOperation("注册")
    public R register(@RequestBody User user) throws ValidationException {
        userService.register(user);
        return R.ok();
    }

    @PostMapping("/userBase")
    @ApiOperation("完善信息")
    public R userBase(@RequestBody User user){
        if (StringUtils.isBlank(user.getEmail()) ||
                StringUtils.isBlank(user.getPaypassword()) ||
                StringUtils.isBlank(user.getUsername())){
            throw new ApiException("信息不可为空");
        }
        user.setPaypassword(new BCryptPasswordEncoder().encode(user.getPaypassword()));
        user.setPaypassSetting((byte)1);
        user.setId(Long.parseLong(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()));
        userService.updateById(user);
        return R.ok();
    }

}
class UseAuthInfoVo{


    private User user;

    private List<UserAuthInfo> userAuthInfoList;

    private List<UserAuthAuditRecord> authAuditRecordList;

    public UseAuthInfoVo(User user,
                         List<UserAuthInfo> userAuthInfos,
                         List<UserAuthAuditRecord> authAuditRecordList){
        this.user = user;
        this.userAuthInfoList = userAuthInfos;
        this.authAuditRecordList = authAuditRecordList;
    }
}


